from rest_framework import generics, status, permissions
from rest_framework.decorators import api_view, permission_classes
from rest_framework.response import Response
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework.filters import OrderingFilter
from .models import (
    NotificationTemplate, Notification,
    EmailLog, SystemAnnouncement, UserNotificationPreference
)
from .serializers import (
    NotificationTemplateSerializer, NotificationSerializer,
    NotificationCreateSerializer, EmailLogSerializer,
    SystemAnnouncementSerializer, SystemAnnouncementCreateSerializer,
    UserNotificationPreferenceSerializer, BulkNotificationSerializer,
    NotificationFilterSerializer
)
from .filters import (
    NotificationFilter, EmailLogFilter,
    SystemAnnouncementFilter
)


class NotificationTemplateListView(generics.ListCreateAPIView):
    queryset = NotificationTemplate.objects.all()
    serializer_class = NotificationTemplateSerializer
    permission_classes = [permissions.IsAdminUser]
    filter_backends = [DjangoFilterBackend, OrderingFilter]
    ordering_fields = ['name', 'created_at']
    ordering = ['-created_at']


class NotificationTemplateDetailView(generics.RetrieveUpdateDestroyAPIView):
    queryset = NotificationTemplate.objects.all()
    serializer_class = NotificationTemplateSerializer
    permission_classes = [permissions.IsAdminUser]


class NotificationListView(generics.ListAPIView):
    serializer_class = NotificationSerializer
    permission_classes = [permissions.IsAuthenticated]
    filter_backends = [DjangoFilterBackend, OrderingFilter]
    filterset_class = NotificationFilter
    ordering_fields = ['created_at', 'priority']
    ordering = ['-created_at']
    
    def get_queryset(self):
        return Notification.objects.filter(user=self.request.user)


class NotificationDetailView(generics.RetrieveAPIView):
    serializer_class = NotificationSerializer
    permission_classes = [permissions.IsAuthenticated]
    
    def get_queryset(self):
        return Notification.objects.filter(user=self.request.user)


class NotificationMarkReadView(generics.UpdateAPIView):
    serializer_class = NotificationSerializer
    permission_classes = [permissions.IsAuthenticated]
    
    def get_queryset(self):
        return Notification.objects.filter(user=self.request.user)
    
    def patch(self, request, *args, **kwargs):
        notification = self.get_object()
        notification.is_read = True
        notification.save()
        
        return Response({
            'message': '通知已标记为已读',
            'notification': NotificationSerializer(notification).data
        })


class NotificationMarkAllReadView(generics.GenericAPIView):
    permission_classes = [permissions.IsAuthenticated]
    
    def post(self, request):
        Notification.objects.filter(
            user=request.user,
            is_read=False
        ).update(is_read=True)
        
        return Response({'message': '所有通知已标记为已读'})


class NotificationStatsView(generics.GenericAPIView):
    permission_classes = [permissions.IsAuthenticated]
    
    def get(self, request):
        user = request.user
        
        total_notifications = Notification.objects.filter(user=user).count()
        unread_notifications = Notification.objects.filter(
            user=user,
            is_read=False
        ).count()
        read_notifications = total_notifications - unread_notifications
        
        notifications_by_type = Notification.objects.filter(
            user=user
        ).values('notification_type').annotate(
            count=Count('id')
        )
        
        return Response({
            'total_notifications': total_notifications,
            'unread_notifications': unread_notifications,
            'read_notifications': read_notifications,
            'notifications_by_type': {
                item['notification_type']: item['count']
                for item in notifications_by_type
            }
        })


class EmailLogListView(generics.ListAPIView):
    queryset = EmailLog.objects.all()
    serializer_class = EmailLogSerializer
    permission_classes = [permissions.IsAdminUser]
    filter_backends = [DjangoFilterBackend, OrderingFilter]
    filterset_class = EmailLogFilter
    ordering_fields = ['sent_at', 'status']
    ordering = ['-sent_at']


class SystemAnnouncementListView(generics.ListAPIView):
    queryset = SystemAnnouncement.objects.filter(
        is_active=True,
        start_date__lte=timezone.now().date(),
        end_date__gte=timezone.now().date()
    )
    serializer_class = SystemAnnouncementSerializer
    permission_classes = [permissions.AllowAny]
    ordering = ['-priority', '-created_at']


class SystemAnnouncementAdminListView(generics.ListCreateAPIView):
    queryset = SystemAnnouncement.objects.all()
    serializer_class = SystemAnnouncementSerializer
    permission_classes = [permissions.IsAdminUser]
    filter_backends = [DjangoFilterBackend, OrderingFilter]
    filterset_class = SystemAnnouncementFilter
    ordering_fields = ['start_date', 'priority', 'created_at']
    ordering = ['-created_at']


class SystemAnnouncementAdminDetailView(generics.RetrieveUpdateDestroyAPIView):
    queryset = SystemAnnouncement.objects.all()
    serializer_class = SystemAnnouncementSerializer
    permission_classes = [permissions.IsAdminUser]


class UserNotificationPreferenceView(generics.RetrieveUpdateAPIView):
    serializer_class = UserNotificationPreferenceSerializer
    permission_classes = [permissions.IsAuthenticated]
    
    def get_object(self):
        preference, created = UserNotificationPreference.objects.get_or_create(
            user=self.request.user
        )
        return preference


class BulkNotificationCreateView(generics.CreateAPIView):
    serializer_class = BulkNotificationSerializer
    permission_classes = [permissions.IsAdminUser]
    
    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        
        data = serializer.validated_data
        users = data['users']
        
        notifications = []
        for user_id in users:
            notification = Notification.objects.create(
                user_id=user_id,
                title=data['title'],
                message=data['message'],
                notification_type=data['notification_type'],
                priority=data['priority'],
                action_url=data.get('action_url', ''),
                expires_at=data.get('expires_at')
            )
            notifications.append(notification)
        
        return Response({
            'message': f'已成功向 {len(notifications)} 个用户发送通知',
            'notifications_count': len(notifications)
        })


@api_view(['POST'])
@permission_classes([permissions.IsAdminUser])
def test_email_template(request):
    from django.core.mail import send_mail
    from django.template.loader import render_to_string
    
    serializer = EmailTemplateTestSerializer(data=request.data)
    serializer.is_valid(raise_exception=True)
    
    data = serializer.validated_data
    
    try:
        template = NotificationTemplate.objects.get(name=data['template_name'])
        
        # 渲染邮件内容
        context = data.get('variables', {})
        subject = template.subject.format(**context)
        message = template.content.format(**context)
        
        # 发送测试邮件
        send_mail(
            subject=subject,
            message=message,
            from_email=settings.DEFAULT_FROM_EMAIL,
            recipient_list=[data['recipient']],
            fail_silently=False,
        )
        
        # 记录邮件日志
        EmailLog.objects.create(
            recipient=data['recipient'],
            subject=subject,
            status='sent',
            template_name=template.name
        )
        
        return Response({'message': '测试邮件已发送'})
        
    except NotificationTemplate.DoesNotExist:
        return Response(
            {'error': '模板不存在'},
            status=status.HTTP_404_NOT_FOUND
        )
    except Exception as e:
        # 记录失败日志
        EmailLog.objects.create(
            recipient=data['recipient'],
            subject=data['template_name'],
            status='failed',
            template_name=data['template_name'],
            error_message=str(e)
        )
        
        return Response(
            {'error': f'邮件发送失败: {str(e)}'},
            status=status.HTTP_500_INTERNAL_SERVER_ERROR
        )


@api_view(['GET'])
@permission_classes([permissions.IsAdminUser])
def email_stats(request):
    from django.db.models import Count
    
    total_sent = EmailLog.objects.count()
    total_failed = EmailLog.objects.filter(status='failed').count()
    
    templates_usage = EmailLog.objects.values('template_name').annotate(
        count=Count('id')
    ).order_by('-count')
    
    success_rate = 0
    if total_sent > 0:
        success_rate = ((total_sent - total_failed) / total_sent) * 100
    
    return Response({
        'total_sent': total_sent,
        'total_failed': total_failed,
        'success_rate': success_rate,
        'templates_usage': {
            item['template_name']: item['count']
            for item in templates_usage
        }
    })
